cap prog drop imusic
prog def  imusic
    version 16
	syntax [anything(name=name)][, Platform(string)] [BRowse] [Stop] [Kind(string)] [Link] [Nl] [List(string)] [Markdown] [Autoplay] [NDescription]   //语法
	preserve //保存工作进度
	*使用了外部命令，如果没有则自动安装外部命令
	cap findfile jsonio.ado
	if  _rc>0 ssc install jsonio
	cap findfile sxpose.ado
	if  _rc>0 ssc install sxpose
	
	*停止播放本地音乐的模块
	if "`stop'" == "stop" {
		foreach exe in Music.UI cloudmusic QQMusic{ 
		!taskkill /f /im `exe'.exe
		}
		exit
	}	

	*默认网易云在线播放
	if "`platform'" == "" {
	local platform = "N"
	} 
	
	*关于platform选择的模块
	if "`platform'" != "" {	
		if "`platform'" != "n" &  "`platform'" != "t" &  "`platform'" != "l" & "`platform'" != "N" &  "`platform'" != "T" &  "`platform'" != "L"{			
			noi di as error "The {bf:platform} you selected is not available in our package."
			noi di as error "Please choose N for Netease , T for Tencent or L for Local and try again"
			exit
		}	
	}

	*默认只取搜索结果的第一位
	if "`list'" == "" local list=1
	
	*默认搜索单曲
	if "`kind'" != "1" & "`kind'" != "10" & "`kind'" != "1000" & "`kind'" != "1014" & "`kind'" != "1009" {
	local kind = "1"
	} //1,单曲；10,专辑；1000,歌单；1014,MV；1009,主播电台；
	
	
	*如果不写歌曲名，随机播放歌曲
	if "`name'" == "" {
	//实际上是网易云的飙升榜
	local platform="Netease"
	clear
	jsonio kv, file(http://music.163.com/api/playlist/detail?id=19723756)
	qui drop if ustrregexm(key, "/creator") == 1
	
	Njsonclean anything , kind(`kind')
	
	forvalues i = 1/`list'{
	local num_`i' = int(runiform(1,100))
	local ID_`i'=valueid[`num_`i'']     //歌曲ID
	local song_name_`i'=valuename[`num_`i''] //歌曲中文名
	local singer_`i'=singer[`num_`i''] //歌手名字
	
	//构造最终的URL
	local URL1="https://music.163.com/#/song?id="
	local URL_`i'="`URL1'`ID_`i''" 
	
	}
	
	//autoplay选项
	if "`autoplay'" != "" {
	local U1 = "https://music.163.com/#/outchain/2/"
	forvalues i = 1/`list' {
	local UU_`i'="`U1'`ID_`i''"
	view browse "`UU_`i''"
	}
	}
	
	
	if "`list'"=="1"{
	if "`nl'" == "" {
	lyrics anything, id(`ID_1')
	}
	}
	

	}
	else {
	mata:str = urlencode("`name'")
	mata:st_local("songname",str) //中文歌名转码
	
	
	*如果选择播放本地音乐	
	if "`platform'" == "l" | "`platform'" == "L" {
		if "$songpath"==""{
		dis as error "请定义音乐存放路径(global songpath),并以\结尾"
		exit
		}
	local filename = "$songpath"+"`name'"+".mp3"
	!start `filename'
	exit
	}

	else{
	*如果选择网易云	
	if "`platform'" == "n" | "`platform'" == "N"{
	if "`kind'" == "1014" local kind = "1" //不支持MV，转为单曲
	
	local URL1="http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s="
	local URL2="&type="
	local URL3="&offset=0&total=true&limit="
	local URL="`URL1'`songname'`URL2'`kind'`URL3'`list'" //构造获取歌曲信息的URL
	clear	
	jsonio kv, file(`URL') //用了外部命令jsonio,获取json文件
		
	Njsonclean anything, kind(`kind')
	
	*搜索的是单曲
	if "`kind'" == "1" {
	forvalue i = 1/`list' {
	local ID_`i'=valueid[`i']     //歌曲ID
	local song_name_`i'=valuename[`i'] //歌曲中文名
	local singer_`i'=singer[`i'] //歌手名字
	}
	
	if "`list'"== "1" {
	if "`nl'" == "" {
	lyrics anything, id(`ID_1')
	}
	}
	
	} 
	
	*搜索的是歌单
	if "`kind'" == "1000" {
	forvalue i = 1/`list' {
	local ID_`i'=valueid[`i']	//歌单ID
	local description_`i'=valuedescription[`i']     //简介
	local song_name_`i'=valuename[`i'] //歌单名字
	local singer_`i'=valuecreator[`i'] //创建人名字	
	}
	} 
	
	*搜索的是专辑
	if "`kind'" == "10" {
	forvalue i = 1/`list' {
	local ID_`i'=valueid[`i']	//专辑ID
	local description_`i'=valuedescription[`i']     //简介，常空
	local song_name_`i'=valuename[`i'] //专辑名字
	local singer_`i'=singer[`i'] //歌手名字	
	}	
	} 

	*搜索的是主播电台
	if "`kind'" == "1009" {
	forvalue i = 1/`list' {
	local ID_`i'=valueid[`i']	//专辑ID
	local description_`i'=valuedesc[`i']     //简介，常空
	local song_name_`i'=valuename[`i'] //电台名字
	local singer_`i'=valuedj[`i'] //创建人名字	
	}	
	} 
	
	
	//autoplay选项
	if "`autoplay'" != "" {
	local U1 = "https://music.163.com/#/outchain/"
	if "`kind'" =="1" local ty=2
	if "`kind'" =="10" local ty=1
	if "`kind'" =="1000" local ty=0
	if "`kind'"=="1009" local ty =4
	forvalues i = 1/`list' {
	local UU_`i'="`U1'`ty'/`ID_`i''"
	view browse "`UU_`i''"
	}
	}
	
	
	//构造最终的URL
	local URL1="https://music.163.com/#/"
	local URL2="?id="
	if "`kind'"=="1" local kind = "song"
	if "`kind'"=="10" local kind = "album"
	if "`kind'"=="1000" local kind = "playlist"
	if "`kind'"=="1002" local kind = "user/home"
	if "`kind'"=="1004" local kind = "video"
	if "`kind'"=="1006" local kind = "song"
	if "`kind'"=="1009" local kind = "djradio"
	forvalue i = 1/`list' {
	local URL_`i'="`URL1'`kind'`URL2'`ID_`i''" 
	}
	}

	*如果选择QQ音乐
	if "`platform'" == "t" | "`platform'" == "T"{
	*转换为QQ的代码
	if "`kind'" == "1" | "`kind'" == "1000" | "`kind'" == "1009" local kind=0 //单曲,歌单和电台不支持，转为搜索单曲
	if "`kind'" == "10" local kind=8 //专辑
	if "`kind'" == "1014" local kind=12 //MV
	
	*获取songmid等各种信息
	local URL1="http://c.y.qq.com/soso/fcgi-bin/client_search_cp?p=1&n="
	local URL2="&w="
	local URL3="&format=json&t="
	local URL="`URL1'`list'`URL2'`songname'`URL3'`kind'" //构造获取歌曲信息的URL
	clear	
	jsonio kv, file(`URL')
	
	*搜索的是单曲
	if "`kind'" == "0" {
	qui keep if ustrregexm(key, "/singer/id/name") == 1 | ustrregexm(key, "/songname") == 1 | ustrregexm(key, "/songmid") == 1
	forvalues i = 1/`list' {
	local ID_`i'=value[3+5*(`i'-1)]     //歌曲ID
	local song_name_`i'=value[4+5*(`i'-1)] //歌曲中文名
	local singer_`i'=value[1+5*(`i'-1)] //歌手名字
	}
	
	//获取歌词
	if "`list'" == "1" {
	clear
	local URL1="http://c.y.qq.com/soso/fcgi-bin/client_search_cp?p=1&n=1&w="
	local URL2="&format=json&t=7"
	local URL="`URL1'`songname'`URL2'" //构造获取歌词的URL
	jsonio kv, file(`URL')
	//如果是纯音乐：
	qui keep if ustrregexm(key, "/data/lyric/list_1/content") == 1
	if ustrregexm(value, "没有填词") == 1 {
	dis as txt char(10) "This is a pure music without lyrics, please enjoy."
	}
	//如果不是纯音乐，截取歌词
	else {
	qui drop key
	qui split value, parse("\n")
	qui sxpose, clear //用了外部命令sxpose
	qui replace _var1=subinstr(_var1,char(10),"",.) //删除换行符
	qui keep if _var1!=" " | _var1!= "" | _var1!= "char(9)"
	qui duplicates tag, generate(dup)
	qui drop if dup==0 | dup==1
	qui duplicates drop
	qui drop dup
	//打印在屏幕上
	if "`nl'" == "" {
	local size = _N
	forvalues i=1/`size'{
	dis as txt _var1[`i']
	}
	}
	}
	}
	}
	
	*搜索的是专辑
	if "`kind'" == "8" {
	qui keep if ustrregexm(key, "/singerName") == 1 | ustrregexm(key, "/albumName") == 1 | ustrregexm(key, "/albumMID") == 1
	forvalues i = 1/`list' {
	local ID_`i'=value[1+5*(`i'-1)]     //专辑ID
	local song_name_`i'=value[2+5*(`i'-1)] //专辑名字
	local singer_`i'=value[4+5*(`i'-1)] //歌手名字
	}
	}

	*搜索的是MV
	if "`kind'" == "12" {
	qui keep if ustrregexm(key, "/singer_name") == 1 | ustrregexm(key, "/mv_name") == 1 | ustrregexm(key, "/v_id") == 1
	forvalues i = 1/`list' {
	local ID_`i'=value[3+3*(`i'-1)]     //专辑ID
	local song_name_`i'=value[1+3*(`i'-1)] //专辑名字
	local singer_`i'=value[2+3*(`i'-1)] //歌手名字
	}
	}
	
	
	*autoplay选项，仅在搜索单曲时生效
	if "`kind'" == "0" {
	if "`autoplay'" != "" {
	*获取播放地址	
	local UURL1="http://u.y.qq.com/cgi-bin/musicu.fcg?format=json&data=%7B%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%22358840384%22%2C%22songmid%22%3A%5B%22"
	local UURL2="%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%221443481947%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A%2218585073516%22%2C%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D"
	forvalues i = 1/`list' {
	local UURL_`i'="`UURL1'`ID_`i''`UURL2'" //构造获取歌曲信息的URL
	clear	
	jsonio kv, file(`UURL_`i'')	
	*构造自动播放地址
	qui keep if ustrregexm(key, "purl") == 1 | ustrregexm(key, "sip") == 1
	local UUURL1=value[2]     //歌曲ID
	local UUURL2=value[1] //歌曲中文名
	local UUURL_`i'="`UUURL1'`UUURL2'"
	view browse "`UUURL_`i''"
	}
	}
	}
	
	*构造最终的URL
	forvalues i = 1/`list' {
	local URL1="https://y.qq.com/n/yqq/"
	if "`kind'"=="0" local kind = "song/"
	if "`kind'"=="8" local kind = "album/"
	if "`kind'"=="12" local kind = "mv/v/"
	local URL2=".html"
	local URL_`i'="`URL1'`kind'`ID_`i''`URL2'"
	}
	
	}	
	
	}	
	}
	
	//打印在屏幕上：歌曲的信息和链接地址
	forvalue i = 1/`list' {
	//有link选项才会显示网址
	if "`link'" != "" dis as txt  `" {browse "`URL_`i''":`URL_`i''}
	dis as txt  `" {browse "`URL_`i''":{bf: <<`song_name_`i''>>, by `singer_`i''}}
	//markdown选项生成markdown格式
	if "`markdown'" != "" {
	dis as txt "[`song_name_`i''](`URL_`i'')"
	}
	if "`ndescription'"==""{
	dis as txt	"`description_`i''"		
	}
	//browse选项自动打开网址
	if "`browse'" != "" {
	view browse "`URL_`i''" //网易云就是网易云音乐的界面，QQ只有一个音频播放页
	}
	
	}
	
	
restore
end

cap prog drop lyrics
prog def lyrics
	syntax anything, ID(string)

	//获取歌词
	local URL1="http://music.163.com/api/song/media?id="
	local URL="`URL1'`id'" //构造获取歌词的URL
	clear
	jsonio kv, file(`URL')
	//如果是纯音乐：
	if ustrregexm(key, "/nolyric_1") == 1 & ustrregexm(value, "true") == 1 {
	dis as txt char(10) "This is a pure music without lyrics, please enjoy."
	}
	//如果不是纯音乐，截取歌词
	else {
	qui keep if ustrregexm(key, "/lyric_1") == 1
	qui drop key
	qui split value, parse("[" "]")
	qui sxpose, clear //用了外部命令sxpose
	qui replace _var1=subinstr(_var1,char(10),"",.) //删除换行符
	qui keep if _var1!=" " | _var1!= "" | _var1!= "char(9)"
	qui duplicates tag, generate(dup)
	qui drop if dup==0
	qui duplicates drop
	qui drop dup
	//打印在屏幕上
	local size = _N
	forvalues i=1/`size'{
	dis as txt _var1[`i']
	}
	}
end

cap prog drop Njsonclean
prog def Njsonclean
syntax anything, kind(string)

qui keep if ustrregexm(key, "\d/name") == 1 | ustrregexm(key, "\d/id") == 1 | ustrregexm(key, "/nickname") == 1 | ustrregexm(key, "/desc") == 1

qui drop if  ustrregexm(key, "Music") == 1
if "`kind'"!= "10" qui drop if ustrregexm(key, "/album")==1

qui split key, parse("/")
drop key key1 key2
qui drop if key5=="id"
qui drop if key4==""
if "`kind'"=="1009" qui drop if key5 == "description"
qui drop key5

qui levelsof key4 //r(r)
if "`kind'"=="1" local num=r(r)-2
if "`kind'"=="10" local num=r(r)-4

qui reshape wide value, i(key3) j(key4) string

if "`kind'"=="1" | "`kind'"=="10" {
qui gen singer=valueartists_1
qui drop valueartists_1
local NN=_N
if `num' - 1 >0  {
forvalues i = 2/`num'{
forvalues n=1/`NN'{
if valueartists_`i'[`n'] !=""{
qui replace singer= singer[`n']+"/"+valueartists_`i'[`n'] if _n == `n'
}
}
qui drop valueartists_`i'
}
}
}

qui split key3,parse("_")
qui destring key32, replace
sort key32

end